package compiler.semanal;

import java.util.LinkedList;

import compiler.abstree.AbsVisitor;
import compiler.abstree.tree.*;
import compiler.report.Report;

public class CycleChecker implements AbsVisitor {
	
	LinkedList<String> path = new LinkedList<String>();

	@Override
	public void visit(AbsAlloc acceptor) {
		
		
	}

	@Override
	public void visit(AbsArrayType acceptor) {
		
		
	}

	@Override
	public void visit(AbsAssignStmt acceptor) {
		
		
	}

	@Override
	public void visit(AbsAtomConst acceptor) {
		
		
	}

	@Override
	public void visit(AbsAtomType acceptor) {
		
		
	}

	@Override
	public void visit(AbsBinExpr acceptor) {
		acceptor.fstExpr.accept(this);
		acceptor.sndExpr.accept(this);
	}

	@Override
	public void visit(AbsBlockStmt acceptor) {
	}

	@Override
	public void visit(AbsCallExpr acceptor) {
		
		
	}

	@Override
	public void visit(AbsConstDecl acceptor) {
		path.add(acceptor.name.name);
		acceptor.value.accept(this);
	}

	@Override
	public void visit(AbsDeclName acceptor) {
	}

	@Override
	public void visit(AbsDecls acceptor) {
		for(AbsDecl decl : acceptor.decls) {
			if(decl instanceof AbsConstDecl) {
				path.clear();
				decl.accept(this);
			}
			else if(decl instanceof AbsTypeDecl) {
				path.clear();
				decl.accept(this);
			}
		}
	}

	@Override
	public void visit(AbsExprStmt acceptor) {
		
		
	}

	@Override
	public void visit(AbsForStmt acceptor) {
		
		
	}

	@Override
	public void visit(AbsFunDecl acceptor) {
		
	}

	@Override
	public void visit(AbsIfStmt acceptor) {
		
		
	}

	@Override
	public void visit(AbsNilConst acceptor) {
		
		
	}

	@Override
	public void visit(AbsPointerType acceptor) {
		
		
	}

	@Override
	public void visit(AbsProcDecl acceptor) {
		
		
	}

	@Override
	public void visit(AbsProgram acceptor) {
		
		
	}

	@Override
	public void visit(AbsRecordType acceptor) {
		
		
	}

	@Override
	public void visit(AbsStmts acceptor) {
		
	}

	@Override
	public void visit(AbsTypeDecl acceptor) {
		path.add(acceptor.name.name);
		acceptor.type.accept(this);
	}

	@Override
	public void visit(AbsTypeName acceptor) {
		if(path.contains(acceptor.name))
			Report.error("Cikel", acceptor.begLine, acceptor.begColumn, 1);
		else {
			AbsDecl decl = SemDesc.getNameDecl(acceptor);
			decl.accept(this);
		}
	}

	@Override
	public void visit(AbsUnExpr acceptor) {
		acceptor.expr.accept(this);
	}

	@Override
	public void visit(AbsValExprs acceptor) {
		
		
	}

	@Override
	public void visit(AbsValName acceptor) {
		if(path.contains(acceptor.name))
			Report.error("Cikel", acceptor.begLine, acceptor.begColumn, 1);
		else {
			AbsDecl decl = SemDesc.getNameDecl(acceptor);
			decl.accept(this);
		}
	}

	@Override
	public void visit(AbsVarDecl acceptor) {
		
		
	}

	@Override
	public void visit(AbsWhileStmt acceptor) {
		
		
	}
	
}